package questions;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * debug 断点跟踪 AbstractQueuedSynchronizer
 *
 *  lock.lock()
 *    ->java.util.concurrent.locks.AbstractQueuedSynchronizer#acquire(int) -->尝试获取锁
 *        -->!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
 *        tryAcquire 尝试获取锁，成功返回true，后面两个方法直接跳过，失败时：
 *        addWaiter： 将当前线程以排他锁的形式，添加到等待队列
 *        acquireQueued：【循环】再次尝试获取锁以后，如果还是没拿到，就LockSupport.part，让线程暂停
 *          >如果当前node的prev是head节点，就再次tryAcquire，成功就执行，失败就↓
 *          >shouldParkAfterFailedAcquire-->
 *
 *
 */
public class AQSDebugDemo {
    private static final Lock lock = new ReentrantLock();
    private static volatile int xx = -1;
    private static volatile int AAA = -1;

    public static void main(String[] args) throws InterruptedException {

        Thread aa = new Thread(() -> {
            //LockSupport.parkNanos
//            lock.tryLock(1,TimeUnit.MILLISECONDS);
            ////LockSupport.park
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "线程\t执行中");
                while (AAA < 0) {
                    TimeUnit.SECONDS.sleep(2);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "thread-AAAA");
        Thread bb = new Thread(() -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "线程\t执行中");
//                TimeUnit.MINUTES.sleep(30);
            } catch (Throwable e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "thread-BBBB");
        Thread cc = new Thread(() -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "线程\t执行中");
//                TimeUnit.MINUTES.sleep(30);
            } catch (Throwable e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "thread-CCCC");
        aa.start();
        while (xx < 0) {
            TimeUnit.SECONDS.sleep(3);
        }
        bb.start();
        while (xx < 1) {
            TimeUnit.SECONDS.sleep(3);
        }
        cc.start();

    }
}
